import React, {memo, useEffect, useState} from "react";
import {Dropdown, Menu, message} from "antd";

import Title from "../../../../components/Title/Title";
import arrDownChecked from "../images/arrangeDownChecked.png";
import arrDown from "../images/arrangeDown.png";
import arrRightChecked from "../images/arrangeRightChecked.png";
import arrRight from "../images/arrangeRight.png";
import {MENU_STYLE} from "../config";
import {count2ScientificCount, deepClone, generateUUID, getRandomColor, sortAndUnique} from "../../../../common/utils";
import {WELL_TYPE} from "../../store/constants";
import {useDispatch, useSelector} from "react-redux";

export default memo(function PlateStandard(props) {
  const {
    sample,
    setSample,
    wells,
    setWells,
    target,
    setTarget,
    wellsCounter,
    setWellsCounter,
    standard,
    setStandard
  } = props;
  const dispatch = useDispatch();
  const {data, standardObj, isCN} = useSelector(state => ({
    data: state.dataReducer.data,
    standardObj: state.plateReducer.standardObj,
    isCN: state.languageReducer.isCN
  }));
  const standardDilutionFactor = ["2X", "5X", "10X", "100X"];
  const standardUnit = ["copies/μL", "ng/μL", "mol/μL"];
  const [isArrDown, setIsArrDown] = useState(true);
  const [standardType, setStandardType] = useState("down");
  const [selectTargetArr, setSelectTargetArr] = useState([]);
  const [standardTargetChannelIndex, setStandardTargetChannelIndex] = useState([]); //  存放standard中选中的target的channelIndex,用于设置浓度
  const [showSelectTarget, setShowSelectTarget] = useState(false);
  let cloneStandard = {};
  let cloneSample = [];
  let cloneWells = [];
  let cloneWellsCounter = [];
  let cloneSelectTargetArr = [];

  useEffect(() => {
    cloneSelectTargetArr = deepClone(selectTargetArr, cloneSelectTargetArr);
    let res = [];
    data.plateSetting.targets.forEach(item => {
      if (res.some(it => it.name === item.name) || !item.name) {
        return;
      }
      // let flag = cloneSelectTargetArr.some(it => {
      //   if (it.uuid === item.uuid) {
      //     res.push({...it, name: item.name});
      //     return true;
      //   }
      // });
      // if (!flag) {
      res.push({...item, selected: false});
      // }
    });
    res.push({name: "ALL", uuid: generateUUID(), isAll: true});
    setSelectTargetArr(res);
  }, [data.plateSetting.targets]);

  useEffect(() => {
    setStandardType(standard.replicateArrange);
  }, [standard]);

  //  改变Standard name
  function changeStandardName(value) {
    cloneStandard = deepClone(standard, cloneStandard);
    cloneStandard.name = value;
    setStandard(cloneStandard);
  }

  //  改变Standard initial quantity
  function changeStandardQuantity(value) {
    let baseName = standard.name.split("-")[0];
    let sampleNameSortArr = [];
    let quantityMap = new Map();
    let sq = Number(value); //  初始浓度
    let dilutionFactor = Number(standard.factor); //  倍数
    cloneWells = deepClone(data.wells, cloneWells);
    cloneWells.forEach(item => item.selected
      && item.sampleName.split("-")[0] === baseName
      && sampleNameSortArr.push(Number(item.sampleName.split("-")[1])));
    sampleNameSortArr = sortAndUnique(sampleNameSortArr); //  对选中的所有sample进行排序和去重,通过"-"后面的数字
    sampleNameSortArr.forEach(item => { //  初始化选中孔位的递增或递减浓度
      quantityMap.set(item, sq);
      standard.increasing ? sq = sq * dilutionFactor.toFixed(3) : sq = sq / dilutionFactor.toFixed(3);
    });
    //  TODO: selectTargetArr 中有ALL 出现了sq是undefined情况,查一下
    selectTargetArr.forEach(item => { //  更改选中target的浓度
        item.selected && cloneWells.forEach(it =>
          it.sampleName.split("-")[0] === baseName
          && (it.lines[item.channelIndex].sq = quantityMap.get(Number(it.sampleName.split("-")[1]))));
      }
    );
    cloneStandard = deepClone(standard, cloneStandard);
    cloneStandard.showInitialQuantity = count2ScientificCount(value);
    cloneStandard.initialQuantity = isNaN(Number(value)) ? 1 : Number(value);
    setStandard(cloneStandard);
    if (isNaN(Number(value)) || Number(value) <= 0) {
      message.warn("Please enter a number greater than 0.");
    }
    setWells(cloneWells);
  }

  //  选择Standard的increasing或decreasing
  function selectStandardIncreasingOrDecreasing(value) {
    cloneStandard = deepClone(standard, cloneStandard);
    cloneStandard.increasing = value;
    setStandard(cloneStandard);
  }

  //  设置Standard(不覆盖,提示重命名)
  function standardOperation() {
    cloneWells = deepClone(wells, cloneWells);
    if (!cloneWells.some(item => item.selected)) {  //  没有选择wells
      return message.warn("Please select wells.");
    }
    if (!standard.name) {
      return message.warn("Please enter standard name.");
    }
    let wellsSelectedCount = 0; //  记录选中well的数量
    cloneSample = deepClone(sample, cloneSample);
    if (standard.replicateArrange !== "handle") {
      let standardNameIndex = Number(standard.name.match(/\d+$/g)), //  standardName后缀(数字)
        baseStandardName, //  standardName前缀
        standardObj = []; //  standard对象数组
      baseStandardName = standard.name.match(/\d+$/g) === null
        ? standard.name
        : standard.name.slice(0, standard.name.length - String(standardNameIndex).length);
      if (cloneSample.some(item => item.name.split("-")[0] === standard.name.split("-")[0])) {
        return message.warn("Rename the standard name.");
      }
      for (let i = 0; i < standard.standardNumber; i++) {
        let standardColor = getRandomColor(), uuid = generateUUID();
        standardObj.push({
          name: baseStandardName + (standardNameIndex + i),
          color: standardColor,
          uuid: uuid
        });
        cloneSample.push({
          opt: true,
          uuid: uuid,
          control: false,
          id: "",
          mark: "",
          name: baseStandardName + (standardNameIndex + i),
          color: standardColor,
          type: WELL_TYPE.STD,
          comments: ""
        });
      }
      let rowNumber = cloneWells.find(item => item.selected).row;  //  第一次出现被选中well的行数
      let colNumber = cloneWells.find(item => item.selected).col;  //  第一次出现被选中well的列数
      let sq = standard.initialQuantity, //  初始浓度
        dilutionFactor = Number(standard.factor), //  倍数
        replicates = standard.replicates; //  重复数
      if (standard.replicateArrange === "down") {
        standardObj.some(item => {
          let replicateCount = 0;
          for (let i = rowNumber * 12; i < rowNumber * 12 + 12; i++) {
            if (cloneWells[i].selected && replicateCount < replicates) {
              replicateCount++;
              wellsSelectedCount++;
              cloneWells[i].sampleName = item.name;
              cloneWells[i].sampleColor = item.color;
              cloneWells[i].type = WELL_TYPE.STD;
              cloneWells[i].sampleUuid = item.uuid;
              //  TODO:需要先选中select中的target才能设置浓度,是否改为默认修改全部target?
              cloneWells[i].targets.forEach(target => cloneWells[i].lines[target.channelIndex].sq = sq);
            }
          }
          standard.increasing ? sq = sq * dilutionFactor.toFixed(3) : sq = sq / dilutionFactor.toFixed(3);
          rowNumber++;
          if (rowNumber > 7) {
            return true;
          }
        });
      } else if (standard.replicateArrange === "right") {
        standardObj.some(item => {
          let replicateCount = 0;
          for (let i = rowNumber * 12 + colNumber; i <= 84 + colNumber; i += 12) {
            if (cloneWells[i].selected && replicateCount < replicates) {
              replicateCount++;
              wellsSelectedCount++;
              cloneWells[i].sampleName = item.name;
              cloneWells[i].sampleColor = item.color;
              cloneWells[i].type = WELL_TYPE.STD;
              cloneWells[i].sampleUuid = item.uuid;
              cloneWells[i].targets.forEach(target => cloneWells[i].lines[target.channelIndex].sq = sq);
            }
          }
          standard.increasing ? sq = sq * dilutionFactor.toFixed(3) : sq = sq / dilutionFactor.toFixed(3);
          colNumber++;
          if (colNumber > 11) {
            return true;
          }
        });
      }
    } else {
      if (cloneSample.some(item => item.name === standard.name)) {
        return message.warn("Rename the standard name.");
      }
      let standardColor = getRandomColor(), uuid = generateUUID();
      cloneSample.push({
        opt: true,
        uuid: uuid,
        control: false,
        id: "",
        mark: "",
        name: standard.name,
        color: standardColor,
        type: WELL_TYPE.STD,
        comments: ""
      });
      cloneWells.forEach(item => {
        if (!item.selected) {
          return;
        }
        item.sampleName = standard.name;
        item.sampleColor = standardColor;
        item.type = WELL_TYPE.STD;
        item.sampleUuid = uuid;
        item.targets.forEach(target => item.lines[target.channelIndex].sq = standard.initialQuantity);
      });
    }
    cloneWellsCounter = deepClone(wellsCounter, cloneWellsCounter);
    cloneWellsCounter[6].count -= wellsSelectedCount;
    cloneWellsCounter[5].count += wellsSelectedCount;
    setWellsCounter(cloneWellsCounter);
    setSample(cloneSample);
    setWells(cloneWells);
  }

  //  选择target
  function selectTarget(target, indey) {
    cloneSelectTargetArr = deepClone(selectTargetArr, cloneSelectTargetArr);
    target.isAll ? cloneSelectTargetArr.forEach(item => item.isAll || (item.selected = true))
      : cloneSelectTargetArr[indey].selected = !cloneSelectTargetArr[indey].selected;
    let standardTargetChannelIndex = [];
    cloneSelectTargetArr.forEach(item => item.selected && standardTargetChannelIndex.push(item.channelIndex));
    setStandardTargetChannelIndex(standardTargetChannelIndex);
    setSelectTargetArr(cloneSelectTargetArr);
  }

  //  选择arrange
  function selectReplicateArrange(value) {
    setIsArrDown(value === "down");
    setStandardType(value);
    cloneStandard = deepClone(standard, cloneStandard);
    cloneStandard.replicateArrange = value;
    setStandard(cloneStandard);
  }

  //  改变number
  function changeNumberOfStandard(value) {
    cloneStandard = deepClone(standard, cloneStandard);
    cloneStandard.standardNumber = value;
    setStandard(cloneStandard);
  }

  //  改变Unit
  function changeUnit(value) {
    cloneStandard = deepClone(standard, cloneStandard);
    cloneStandard.unit = value;
    setStandard(cloneStandard);
  }


  //  改变factor
  function changeFactor(value, index) {
    cloneStandard = deepClone(standard, cloneStandard);
    // cloneStandard.factor = index === undefined ? (value?.split('X')[0]) : value;
    switch (index) {
      case undefined:
        cloneStandard.factor = value?.split('X')[0];
        break;
      case "toNumber":
        cloneStandard.factor = Number(value?.split('X')[0]);
        break;
      default:
        cloneStandard.factor = value;
        break;
    }
    setStandard(cloneStandard);
  }

  //  改变replicates
  function changeReplicates(value) {
    cloneStandard = deepClone(standard, cloneStandard);
    cloneStandard.replicates = value;
    setStandard(cloneStandard);
  }

  return (
    <div className="platePageStandard">
      <Title name={isCN ? "标准" : "Standard"} btnLeft={isCN ? "应用" : "STD Task"} btnLeftAction={standardOperation}/>
      <ul>
        <li>
          <div>
            <div>{isCN ? "选择目标基因" : "Select Target"}</div>
            <Dropdown
              overlay={
                <Menu>
                  {
                    selectTargetArr.map((item, index) => (
                      <Menu.Item key={item.uuid}>
                        <div style={MENU_STYLE}
                             onClick={() => selectTarget(item, index)}
                             className={item.selected ? "standardSelectTarget" : null}
                        >{item.name}
                        </div>
                      </Menu.Item>
                    ))
                  }
                </Menu>
              }
              overlayClassName="antdDropDownStyle"
              placement="topCenter"
              trigger={['click']}
              visible={showSelectTarget}
            >
              <div onClick={() => setShowSelectTarget(!showSelectTarget)}>Select</div>
            </Dropdown>
          </div>
          <div>
            <div>{isCN ? "名称" : "Name"}</div>
            <input type="text" value={standard.name || ""} onChange={e => changeStandardName(e.target.value)}/>
          </div>
        </li>
        <li>
          <div>
            <div style={{width: 140}}>{isCN ? "标准品数目" : "Number of Standard"}</div>
            <input type="number" style={{width: 80}} value={standard.standardNumber || ""}
                   onChange={e => changeNumberOfStandard(Number(e.target.value))}/>
          </div>
          <div>
            <div>{isCN ? "起始浓度" : "Initial Quantity"}</div>
            <input key={standard.initialQuantity} type="text" defaultValue={standard.showInitialQuantity}
                   onBlur={e => changeStandardQuantity(e.target.value)}/>
          </div>
        </li>
        <li>
          <div>
            <div>{isCN ? "单位" : "Unit"}</div>
            <Dropdown
              overlay={
                <Menu>
                  {
                    standardUnit.map(item => (
                      <Menu.Item key={item}>
                        <div style={MENU_STYLE} onClick={() => changeUnit(item)}>{item}</div>
                      </Menu.Item>
                    ))
                  }
                </Menu>
              }
              placement="topCenter"
              trigger={['click']}
            >
              <input type="text" key={standard.unit} value={standard.unit}
                     onChange={e => changeUnit(e.target.value)}/>
            </Dropdown>
          </div>
          <div>
            <div>{isCN ? "倍比稀释" : "Dilution Factor"}</div>
            <Dropdown
              overlay={
                <Menu>
                  {
                    standardDilutionFactor.map((item, index) => (
                      <Menu.Item key={item}>
                        <div style={MENU_STYLE} onClick={() => changeFactor((parseInt(item)), index)}>{item}</div>
                      </Menu.Item>
                    ))
                  }
                </Menu>
              }
              placement="topCenter"
              trigger={['click']}
            >
              <input type="text" value={`${standard.factor}X`}
                     name="factor"
                     onChange={e => changeFactor(e.target.value, undefined)}
                     onBlur={e => changeFactor(e.target.value, "toNumber")}/>
            </Dropdown>
          </div>
        </li>
        <li>
          <div>
            <div style={{width: 140}}>{isCN ? "重复数" : "Number of Replicate"}</div>
            <input type="number" style={{width: 80}}
                   value={standard.replicates}
                   onChange={e => changeReplicates(Number(e.target.value))}
            />
          </div>
          <label htmlFor="increasing">
            <input type="radio" id="increasing" checked={standard.increasing}
                   onChange={() => selectStandardIncreasingOrDecreasing(true)}/>
            <div>{isCN ? "升序" : "Increasing"}</div>
          </label>
          <label htmlFor="decreasing">
            <input type="radio" id="decreasing" checked={!standard.increasing}
                   onChange={() => selectStandardIncreasingOrDecreasing(false)}/>
            <div>{isCN ? "降序" : "Decreasing"}</div>
          </label>
        </li>
        <li>
          <div>
            <div>{isCN ? "排布方式" : "Replicate Arrange"}</div>
            <div onClick={() => selectReplicateArrange("down")}
                 style={{backgroundImage: standardType === "down" ? `url(${arrDownChecked})` : `url(${arrDown})`}}
            />
            <div onClick={() => selectReplicateArrange("right")}
                 style={{backgroundImage: standardType === "right" ? `url(${arrRightChecked})` : `url(${arrRight})`}}
            />
            <div onClick={() => selectReplicateArrange("handle")}
                 style={standardType === "handle" ? {color: "#fff", background: "#213040"} : {}}
            >M
            </div>
          </div>
        </li>
      </ul>
    </div>
  );
});